#include"IGameApp.h"
#include"windows.h"
#include"d3dx9.h"
#include"atltime.h"
#include"dinput.h"
#include"time.h"

#include"FrameWorkGlobal.h"

using namespace std;

// ham chinh
IGameApp::IGameApp(HINSTANCE _hInstance,int _Mode,bool _IsFullScreen,int _frameRate)
{
	m_hInstance=_hInstance;
	m_hWnd=NULL;
	m_pMode=_Mode;
	m_pIsFullScreen=_IsFullScreen;
	SetScreenDimension();
	m_pFPS=_frameRate;
}
void IGameApp::SetScreenDimension()
{
	switch (m_pMode)
	{
	case GAME_SCREEN_RESOLUTION_640_480_24:
		m_pScreenWidth = 640; 
		m_pScreenHeight = 480;
		break;

	case GAME_SCREEN_RESOLUTION_800_600_24:
		m_pScreenWidth = 800; 
		m_pScreenHeight = 600;
		break;

	case GAME_SCREEN_RESOLUTION_1024_768_24:
		m_pScreenWidth = 1024; 
		m_pScreenHeight = 768;
		break;

	default: 
		m_pScreenWidth = 800; 
		m_pScreenHeight = 600;
		break;
	}
}
int IGameApp::Init()
{
	
	if(!InitWindow())
	{
		MessageBox(m_hWnd,"ERROR: Can not initial window","uitse.com",MB_OK);
		return 0;
	}
	m_DxManager=new DXManager(m_hWnd,m_hInstance,m_pScreenWidth,m_pScreenHeight,m_pIsFullScreen);
	
	if(!m_DxManager->Init())
	{
		MessageBox(m_hWnd,"ERROR : Can not initial directX device ","uitse.com",MB_OK);
		return 0;
	}
	if(!m_DxManager->InitKeyboardDevice())
	{
		MessageBox(m_hWnd,"Error : Can not initial directX input","uitse.com",MB_OK);
		return 0;
	}
	LoadResource();
	return 1;
}
/************************************************************************/
/*****************			Initial window			*********************/
/************************************************************************/
bool IGameApp::InitWindow()
{
	WNDCLASS w;
	w.cbClsExtra=0;
	w.cbWndExtra=0;
	w.lpfnWndProc=(WNDPROC)WndProc;
	w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	w.hCursor=LoadCursor(NULL,IDC_ARROW);
	w.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	w.lpszClassName=szAppName;
	w.lpszMenuName=NULL;
	w.style=CS_BYTEALIGNCLIENT|CS_HREDRAW|CS_VREDRAW;
	w.hInstance=m_hInstance;
	if(!RegisterClass(&w))
		return false;
	TraceGame(L"(INFO)Register Window Successful");
	// initial window
	DWORD Style;
	Style=m_pIsFullScreen ? WS_EX_TOPMOST|WS_POPUP|WS_VISIBLE: WS_OVERLAPPEDWINDOW;
	m_hWnd=CreateWindow
	(
		szAppName,
		szAppName,
		Style,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		m_pScreenWidth,
		m_pScreenHeight,
		NULL,
		NULL,
		m_hInstance,
		NULL
	);
	if(m_hWnd==NULL)
		return false;
	TraceGame(L"(INFO)Create Window Successful");
	ShowWindow(m_hWnd,SW_SHOW);
	UpdateWindow(m_hWnd);
	
	return true;
}
/************************************************************************/
/*****************		IGameApp Run					*********************/
/************************************************************************/
void IGameApp::Run()
{
	int curVolume=0;
	int volChange=1000;
	MSG msg;
	ZeroMemory(&msg,sizeof(msg));
	DWORD frame_start = GetTickCount();
	DWORD tick_per_frame = 1000 / m_pFPS;
	while(msg.message!=WM_QUIT)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			curVolume+=volChange;
			if((curVolume<=10000)||(curVolume>=10000))
				volChange*=-1;
			KeyBoardProcessing();
			InputDownProcessing(m_DeltaTime);
			InputUpProcessing();
			DWORD now = GetTickCount();

			// Get Display the frame rate
			int nFrameRate = m_Timer.GetFrameRate();
			
			m_DeltaTime = now - frame_start; 
			if (m_DeltaTime >= tick_per_frame)
			{
				frame_start = now;
				//Render();
			}

			m_Timer.Tick();
			static int nLastFrameRate = 0;
			if ( nFrameRate!=nLastFrameRate  )
			{
				Render();
				static char FPSBuffer[20];
				m_Timer.GetFrameRate( FPSBuffer );
				nLastFrameRate = nFrameRate;
				SetWindowText( m_hWnd, FPSBuffer );

			} // End if Frame Rate Altered
		}
	}
	return ;
}

/************************************************************************/
/*****************		Control Window Processing	*********************/
/************************************************************************/
LRESULT CALLBACK IGameApp::WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	
	switch(msg)
	{
		case WM_DESTROY:
					PostQuitMessage(0);
					break;
		default:return DefWindowProc(hwnd,msg,wParam,lParam);
	}
	return 0;
}


/************************************************************************/
/*****************			Exit Game				*********************/
/************************************************************************/

void IGameApp::Destroy()
{
	m_DxManager->Destroy();
	
}
/************************************************************************/
/*****************			Render into Screen		*********************/
/************************************************************************/
void IGameApp::Render()
{
	m_DxManager->BeginRender();
	
	m_DxManager->EndRender();
	m_DxManager->GetD3DDDevice()->Present(NULL,NULL,NULL,NULL);
	
	

}

/************************************************************************/
/*****************			Control Keyboard			*********************/
/************************************************************************/
void IGameApp::KeyBoardProcessing()
{
	m_DxManager->m_pKeyboardDevice->GetDeviceState(sizeof(m_pKeys),m_pKeys);
	if(IsKeyDown(DIK_F10))
	{
		PostQuitMessage(0);
		return;
	}
	DWORD dwElements=KEYBOARD_BUFFER_SIZE;
	m_DxManager->m_pKeyboardDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),m_pKeyEvent,&dwElements,0);
	for(DWORD i=0;i<dwElements;i++)
	{
		int KeyCode=m_pKeyEvent[i].dwOfs;
		int KeyState=m_pKeyEvent[i].dwData;
		if((KeyState	&	0x80)>0)
		{
			OnKeyDown(KeyCode);
		}
		else
			OnKeyUp(KeyCode);
	}
}
int IGameApp::IsKeyDown(int KeyCode)
{
	return (m_pKeys[KeyCode]	&	0x80)>0;
}
void IGameApp::OnKeyDown(int KeyCode){}
void IGameApp::OnKeyUp(int KeyCode){}
void IGameApp::Update(){}
